// dict.d: The Dictionary interface and base class, as the M part of the MVC structure
// Author: Wei Li (oldrev@gmail.com)
// License: GPL

module dayudict.dict;

import std.string;

import dayudict.sqlite.sqlite3db;


/**
  * 一个词条
  * 
  */
struct VocabularyEntry
{
	char[] word;			// 单词
	char[] phonetics;		// 音标
	char[] translation;		// 翻译 
	
	public bool valid()
	{
		return word.length > 0 && phonetics.length > 0 && 
			translation.length > 0;
	}

}


/**
  * 建模一个词库 
  * 属于MVC 中的 M 部分
  */
interface IDictionary
{
	/**
	  * 查找一个模式的所有匹配单词
	  */
	char[][] match(char[] pattern);

	/**
	  * 查找一个单词
	  */
	VocabularyEntry lookup(char[] word);
}

/**
  * SQLite 词库
  */
class SqliteDictionary : IDictionary
{
	invariant
	{
		assert(m_db !is null); 
	}

	private const char[] MatchSql = `SELECT word FROM dictionary WHERE word LIKE '%s'`;
	private const char[] LookupSql = `SELECT * FROM dictionary WHERE word="%s"`;

	private Sqlite3Connection m_db = null;

	public this(char[] path)
	in
	{
		assert(path !is null);
		assert(path.length > 0);
	}
	body
	{
		m_db = new Sqlite3Connection(path);
	}

	public ~this()
	{
		close();
	}

	public void close()
	{
		m_db.close();
	}

	public override char[][] match(char[] pattern)
	in
	{
		assert(pattern !is null);
		assert(pattern.length > 0);
	}
	body
	{
		char[][] words;
		char[] sql = format(MatchSql, pattern);
		Sqlite3DataReader reader = m_db.query(sql);
		while(reader.read)
		{
			words ~= reader.getString(reader.getOrdinal("word"));
		}
		return words;
	}

	public override VocabularyEntry lookup(char[] word)
	in
	{
		assert(word !is null);
		assert(word.length > 0);
	}
	out(r)
	{
		assert(r.valid); 	
	}
	body
	{
		//FIXME: 安全问题
		char[] sql = format(LookupSql, word);
		Sqlite3DataReader reader = m_db.query(sql);
		if(!reader.read)
			throw new DBException("Failed to read result", 0);

		VocabularyEntry entry;
		entry.word = reader.getString(reader.getOrdinal("word"));
		entry.phonetics = reader.getString(reader.getOrdinal("phonetics"));
		entry.translation = reader.getString(reader.getOrdinal("translation"));

		return entry;
	}

}


/**
  * 虚拟词库基类，用于那些不需要词库文件，而是可以通过计算查询的词库类型，比如汉字查拼音
  */
abstract class VirtualDictionary : IDictionary
{
}
